"------------------------
" git related function
"------------------------
function! GitBranch()
    return get(b:, 'git_branch', '')
endfunction
function! GitRootPath()
    return get(b:, 'git_root_path', '')
endfunction
function! GitFileName()
    let root = GitRootPath()
    let leng = len(root)
    let path = substitute(Expand('%:p'), '\\', '/', 'g')
    if WINDOWS()
        if path[leng] == '/'
            return path[leng+1:]
        else
            return path[leng:]
        endif
    else
        return path[len(root):]
    endif
endfunction
function! UpdateBufGit()
    if WINDOWS()
        let idx = -1
    else
        let idx = 0
    endif
    if g:git_version > 1.8
        let b:git_root_path = split(system('git rev-parse --show-toplevel'), "\\n")[idx]  . '/'
        if b:git_root_path =~ 'fatal:' && b:git_root_path =~ 'git'
            let b:git_branch = ''
            let b:git_root_path = ''
        else
            if Expand('%:t') !~? 'Tagbar\|Vista\|Gundo\|NERD\|coc\|fern\|netrw\|neo-tree' && &filetype !~ 'vimfiler' && index(['nofile', 'popup'], &buftype) < 0
                try
                    let b:git_branch = split(system('git rev-parse --abbrev-ref HEAD'), '\n')[idx]
                    if b:git_branch =~ 'fatal:'
                        let b:git_branch = ''
                        let b:git_root_path = ''
                    endif
                catch /.*/
                    let b:git_branch = ''
                    let b:git_root_path = ''
                endtry
            else
                let b:git_branch = ''
                let b:git_root_path = ''
            endif
        endif
    else
        let b:git_branch = ''
        let b:git_root_path = ''
    endif
endfunction
augroup UpdateBufGit
    autocmd!
    autocmd WinEnter,BufCreate,BufEnter * call UpdateBufGit()
augroup END
"------------------------
" fugitve and others
"------------------------
if Installed('vim-fugitive')
    nnoremap <M-G>  :Git
    nnoremap <M-g>U :Git push<Space>
    nnoremap <silent><M-g>m :Git commit -av<Cr>
    nnoremap <silent><M-g>u :Git push<CR>
    " compare with history version
    let g:fugitive_summary_format = "%as-[%an]: %s"
    nnoremap <silent><M-g>h :Git log --pretty=format:"%h\|\|%as-[%an]: %s" -- %<cr>
    nnoremap <silent><M-g>d 0"ayiw:bw<cr>:rightbelow Gvdiff <c-r>a<cr>
    " git diff
    nnoremap <silent><M-g>v :Gvdiffsplit<Cr>
    nnoremap <silent><M-g>s :Gdiffsplit<Cr>
    nnoremap <silent><M-g>2 :diffget //2<CR>]
    nnoremap <silent><M-g>3 :diffget //3<CR>]
    " gitblame
    nnoremap <silent>,<Tab> :Git blame<Cr>
    if Installed('blamer.nvim')
        let g:blamer_date_format = '%Y/%m/%d %H:%M'
        let g:blamer_show_in_insert_modes = 0
        let g:blamer_prefix = ' >> '
        nnoremap ,<Cr> :BlamerToggle<Cr>
    endif
    " flog
    if Installed('vim-flog')
        nnoremap <silent><M-g>f :Flog
    endif
elseif Installed('asyncrun.vim') && g:has_terminal && UNIX()
    nnoremap <M-G>  :AsyncRun -mode=term -focus=1 git
    nnoremap <M-g>U :AsyncRun -mode=term -focus=1 git push<Space>
    nnoremap <M-g>m :AsyncRun -mode=term -focus=1 git commit -a -m ""<Left>
    nnoremap <M-g>u :AsyncRun -mode=term -focus=1 git push<Cr>
else
    nnoremap <M-G>  :!git
    nnoremap <M-g>U :!git push<Space>
    nnoremap <M-g>m :!git commit -a -m ""<Left>
    nnoremap <M-g>u :!git push<Cr>
endif
" commit history
if InstalledFzf()
    nnoremap <silent><M-g>c :FzfCommits<Cr>
    nnoremap <silent><M-g>b :FzfBCommits<Cr>
endif
" ---------------------------------
" tig lazygit intergrated
" ---------------------------------
if Installed('vim-floaterm') && g:has_popup_floating
    if executable('tig')
        command! Tig exec "FloatermNew --height=0.9 --width=0.9 --title=tig --wintype=float --postion=center tig"
        nnoremap <silent><M-g>t :Tig<Cr>
    endif
    if executable('lazygit')
        command! LazyGit exec "FloatermNew --height=0.9 --width=0.9 --title=lazygit --wintype=float --postion=center lazygit"
        nnoremap <silent><M-g>l :LazyGit<Cr>
    endif
endif
"########## Merge ##########{{{
let s:mergeSources = {
            \  'L':      1,
            \  'LOCAL':  1,
            \  'B':      2,
            \  'BASE':   2,
            \  'R':      3,
            \  'REMOTE': 3,
            \  'M':      4,
            \  'MERGE':  4,
            \}
function!  git#createMergeTab(...)
    " Map source name to buffer number
    if a:0 > 0
        let l:sources = []
        for item in a:000
            if has_key(s:mergeSources, toupper(item))
                call add(l:sources, get(s:mergeSources, toupper(item)))
            else
                echo 'Unrecognized source: ' . item
                return
            endif
        endfor
    else
        let l:sources = [1, 4, 3]
    endif
    let l:mergeBufIndex = max([index(l:sources, 4), 0]) + 1
    tabnew
    let i = 0
    while i < len(l:sources) - 1
        exec 'buf ' . l:sources[i]
        rightbelow vsp
        let i = i + 1
    endwhile
    exec 'buf ' . l:sources[i]
    windo diffthis
    exec l:mergeBufIndex . 'wincmd w'
endfunc
command! -nargs=* MergeTab call  git#createMergeTab(<f-args>)
nnoremap <M-g>M :MergeTab<space>
